package com.thinking.in.spring.ioc.dependency.injection;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 依赖注入：
 *      1 ：Xml方式的 Setter 方法的注入,手动注入
 *      2 : Annotation 的方式注入
 *      3 : Api 的方式
 * @author zjiajia
 * @date 2021/12/31 13:17
 */
public class ApiDependencyConstructInjectionDemo {

    public static void main(String[] args) {
        // 创建 BeanFactory
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

        // xml Bean定义信息 Reader
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        // 加载配置信息  ，解析 装载 配置文件
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:/META-INF/dependency-lookup-context.xml");


        // Api 的方式 ，手动的 创建 BeanDefinition
        BeanDefinition userHolderBeanDefinition = createUserHolderBeanDefinition();
        applicationContext.registerBeanDefinition("userHolder",userHolderBeanDefinition);


        // 启动Spring 应用上下文
        applicationContext.refresh();

        // 注解形式的注入的时候，也是可以用 XmlBean的配置信息的，都是将Bean信息加载到了 BeanDefinitionRegister中了
        UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);

        System.out.println(userHolder);


        // 关闭应用上下文
        applicationContext.close();


    }

    /**
     * 注解的形式 ：
     *          首先拿到 UserHolder Bean
     *          让后将 User 作为参数传入
     * @param user      user
     * @return          userHolder 
     */
 /*   @Bean
    public UserHolder userHolder(User user){

        return new UserHolder(user);
    }*/

    /**
     * 创造一个 UserHolder 的  BeanDefinition
     * @return      BeanDefinition
     */
    private static BeanDefinition createUserHolderBeanDefinition(){

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserHolder.class);

        // Api的方式,构造器的方式注入
        beanDefinitionBuilder.addConstructorArgReference("user");


        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();


        return beanDefinition;


    }
}
